﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.OleDb;
using System.Data;

namespace SixLottery.Data
{
    public class Access
    {
        private static readonly int CommandTimeout = 100;

        private string mConnectionString;

        private static object sLockObj = new object();

        private static Access sInstance;

        public string ConnectionString
        {
            get { return mConnectionString; }
            set { mConnectionString = value; }
        }

        public Access(string connectionString)
        {
            this.mConnectionString = connectionString;
        }

        public static Access GetInstance(string connectionString)
        {
            if (sInstance == null)
            {
                lock (sLockObj)
                {
                    if (sInstance == null)
                    {
                        sInstance = new Access(connectionString);
                    }
                }
            }

            return sInstance;
        }

        public T ExecuteScaler<T>(string sql, Dictionary<string, object> args)
        {
            using (OleDbConnection conn = new OleDbConnection(mConnectionString))
            {
                OleDbCommand cmd = PrepareCommand(conn, sql, args);
                conn.Open();

                T result = default(T);
                object obj = cmd.ExecuteScalar();
                if (obj!=null)
                {
                    result = (T)cmd.ExecuteScalar(); 
                }                

                cmd.Dispose();
                conn.Close();

                return result;
            } 
        }

        public void Execute(string sql, Dictionary<string, object> args)
        {
            using (OleDbConnection conn = new OleDbConnection(mConnectionString))
            {
                OleDbCommand cmd = PrepareCommand(conn, sql, args);
                conn.Open();
                int effect = cmd.ExecuteNonQuery();
                cmd.Dispose();
                conn.Close();
            }          
        }

        public DataTable GetDataTable(string sql, Dictionary<string, object> args)
        {
            DataTable dt = new DataTable();
            using (OleDbConnection conn = new OleDbConnection(mConnectionString))
            {
                OleDbCommand cmd = PrepareCommand(conn, sql, args);

                OleDbDataAdapter da = new OleDbDataAdapter(cmd);
                da.Fill(dt);
            }

            return dt;
        }

        private OleDbCommand PrepareCommand(OleDbConnection conn, string sql, Dictionary<string, object> args)
        {
            OleDbCommand cmd = conn.CreateCommand();
            cmd.CommandText = sql;
            cmd.CommandTimeout = CommandTimeout;
            cmd.CommandType = CommandType.Text;

            if (null != args && args.Count > 0)
            {
                foreach (string key in args.Keys)
                {
                    cmd.Parameters.AddWithValue(key, args[key]);
                }
            }           

            return cmd;
        }

    }
}
